//
//  BLRECKit.m
//  vrmuApp
//
//  Created by Benz.L on 24/07/2018.
//  Copyright © 2018 广东瑞亚传媒发展有限公司. All rights reserved.
//

#import "BLRECKit.h"
#import <ReplayKit/ReplayKit.h>
#import <Photos/Photos.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import <Photos/Photos.h>


static void excute_block_in_main_queue_safely(dispatch_block_t block) {
    if (![NSThread currentThread].isMainThread) {
        dispatch_sync(dispatch_get_main_queue(), block);
    } else {
        block();
    }
}

#define WEAKREF(obj) __weak typeof(obj) weak = obj;

#define kVideoOutPath VideoCachePath()

static NSString *path = nil;
NSString *VideoCachePath() {
    if (!path) {
        NSString *outputURL = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
        path = [[outputURL stringByAppendingPathComponent:@"REC"] stringByAppendingPathExtension:@"mp4"];
    }
    return path;
}

@interface JYPhotoVideoKit : NSObject
+ (void)compressVideo:(PHAsset *)video complete:(void(^)(NSError *error, NSData *data))complete;
@end


@interface BLRECKit()<RPPreviewViewControllerDelegate>
@property(nonatomic, strong) AVAssetWriter *assetWriter;
@property(nonatomic, strong) AVAssetWriterInput *videoInput;
@property(nonatomic, strong) AVAssetWriterInput *audioInput;
@property(nonatomic, assign) RECState internalState;
@property(nonatomic, strong) AVAssetWriterInput *micInput;
@property(nonatomic, assign) BOOL sessionStarted;
@end

@implementation BLRECKit

+ (BOOL)canREC {
	return [RPScreenRecorder sharedRecorder].available;
}

+ (void)requireAuthorizeIfNeeded:(void(^)(BOOL granted))complete {
	AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
	if (status!=AVAuthorizationStatusAuthorized) {
		[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
			if (complete) {
				complete(granted);
			}
		}];
	}
	else {
		if (complete) {
			complete(status==AVAuthorizationStatusAuthorized);
		}
	}
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _internalState = RECStateNone;
    }
    return self;
}

- (void)startREC {
	if ([self.class canREC]) {
        [self startScreenRecording];
	}
}

- (void)stopREC {
    [self stopScreenRecording];
}

- (RECState)state {
    return _internalState;
}

- (void)dealloc {
    //[_assetWriter removeObserver:self forKeyPath:@"status"];
}
#pragma mark - RPPreviewViewControllerDelegate

- (void)previewControllerDidFinish:(RPPreviewViewController *)previewController {
    
}

- (void)previewController:(RPPreviewViewController *)previewController didFinishWithActivityTypes:(NSSet <NSString *> *)activityTypes {
    [previewController dismissViewControllerAnimated:YES completion:nil];
    if ([activityTypes containsObject:@"com.apple.UIKit.activity.SaveToCameraRoll"]) {
        
    }
};

#pragma mark - Private

- (void)startScreenRecording {
    NSLog();
    if ([self.class canREC]) {
        if ([RPScreenRecorder sharedRecorder].isRecording) {
            return;
        }
        
        if ([[NSFileManager defaultManager] fileExistsAtPath:kVideoOutPath]) { // 清除已存在的文件
            [[NSFileManager defaultManager] removeItemAtPath:kVideoOutPath error:nil];
        }
        
        WEAKREF(self)
        if (/*@available(iOS 11.0, *)*/0) {
            [self resetWriter];
            if (self.assetWriter.status==AVAssetWriterStatusUnknown) {
                if ([self.assetWriter canAddInput:self.videoInput]) {
                    [self.videoInput setExpectsMediaDataInRealTime:YES];
                    [self.videoInput setMediaTimeScale:60];
                    [self.assetWriter addInput:self.videoInput];
                }
                
                if ([self.assetWriter canAddInput:self.audioInput]) {
                    [self.audioInput setExpectsMediaDataInRealTime:YES];
                    [self.assetWriter addInput:self.audioInput];
                }
                
                [self.assetWriter setMovieTimeScale:60];
            }
            
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                excute_block_in_main_queue_safely(^{
					__strong typeof(weak) strong = weak;
                    if (granted) {
                        [[RPScreenRecorder sharedRecorder] setMicrophoneEnabled:weak.micEnable];
                        [[RPScreenRecorder sharedRecorder] startCaptureWithHandler:^(CMSampleBufferRef  _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) {
                            if (CMSampleBufferIsValid(sampleBuffer)) {
                                [weak captureSampleBuffer:sampleBuffer withBufferType:bufferType error:error];
                            }
                        } completionHandler:^(NSError * _Nullable error) {
                            excute_block_in_main_queue_safely(^{
                                if (!error) {
                                    strong.internalState = RECStateRecording;
                                    AVAudioSession *session = [AVAudioSession sharedInstance];
                                    [session setActive:YES error:nil];
                                    // Start recording
                                    NSLog(@"Recording started successfully.");
                                }
                                else{
									strong.internalState = BLRECStateFailure;
                                    if ([strong.delegate respondsToSelector:@selector(recKit:didFailure:)]) {
                                        [strong.delegate recKit:strong didFailure:error];
                                    }
                                }
                            });
                        }];
                    }
					else {
						strong.internalState = BLRECStateNotAuthorized;
					}
                });
            }];
        } else {
            // Fallback on earlier versions
            [[RPScreenRecorder sharedRecorder] startRecordingWithMicrophoneEnabled:_micEnable handler:^(NSError * _Nullable error) {
                excute_block_in_main_queue_safely(^{
                    if (error && [weak.delegate respondsToSelector:@selector(recKit:didFailure:)]) {
                        [weak.delegate recKit:weak didFailure:error];
                    }
                    weak.internalState = error?BLRECStateFailure:RECStateRecording;
                });
            }];
        }
    }
}

- (void)stopScreenRecording {
    if ([self.class canREC]) {
        WEAKREF(self)
        if (/*@available(iOS 11.0, *)*/0) {
            [[RPScreenRecorder sharedRecorder] stopCaptureWithHandler:^(NSError * _Nullable error) {
                // Finishes up the writer.
                if (self.assetWriter.status==AVAssetWriterStatusWriting) {
                    [self.videoInput markAsFinished];
                    [self.audioInput markAsFinished];
                    if (self.micEnable) {
                        [self.micInput markAsFinished];
                    }
                    [self.assetWriter finishWritingWithCompletionHandler:^{
                        NSLog(@"writer status = %@", @(self.assetWriter.status));
                        // Saves the output video to the user photo album.
                        //[self saveVideoToAlbum];
                        excute_block_in_main_queue_safely(^{
                            __strong typeof(weak) strong = weak;
                            if (!error) {
                                if ([strong.delegate respondsToSelector:@selector(recKit:didFinishREC:)]) {
                                    [strong.delegate recKit:strong didFinishREC:[NSURL fileURLWithPath:kVideoOutPath]];
                                }
                                strong.internalState = BLRECStateFinished;
                            }
                            else {
                                if ([strong.delegate respondsToSelector:@selector(recKit:didFailure:)]) {
                                    [strong.delegate recKit:strong didFailure:error];
                                }
                                strong.internalState = BLRECStateFailure;
                            }
                        });
                    }];
                }
            }];
        }
        else {
            [[RPScreenRecorder sharedRecorder] stopRecordingWithHandler:^(RPPreviewViewController * _Nullable previewViewController, NSError * _Nullable error) {
                if (error) {
                    excute_block_in_main_queue_safely(^{
                        if ([weak.delegate respondsToSelector:@selector(recKit:didFailure:)]) {
                            [weak.delegate recKit:weak didFailure:error];
                        }
                        weak.internalState = BLRECStateFailure;
                    });
                }
                else {
                    NSURL *movieURL =  [previewViewController valueForKey:@"movieURL"];
					/*
					[PHPhotoLibrary.sharedPhotoLibrary performChanges:^{
						PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:movieURL];
						[request addResourceWithType:PHAssetResourceTypeVideo fileURL:movieURL options:PHAssetResourceCreationOptions.new];
					} completionHandler:^(BOOL success, NSError * _Nullable error) {
						if ([weak.delegate respondsToSelector:@selector(recKit:didFailure:)]) {
							[weak.delegate recKit:weak didFailure:error];
						}
						weak.internalState = BLRECStateFailure;
					}];
					 */
					
                    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
                    [library writeVideoAtPathToSavedPhotosAlbum:movieURL completionBlock:^(NSURL *assetURL, NSError *error) {
                        if (!error) {
							PHAsset *asset = [PHAsset fetchAssetsWithALAssetURLs:@[assetURL] options:nil].firstObject;
							[self exportAsset:asset complete:^(NSError *error, NSURL *url) {
								if (error) {
									if ([weak.delegate respondsToSelector:@selector(recKit:didFailure:)]) {
										[weak.delegate recKit:weak didFailure:error];
									}
									weak.internalState = BLRECStateFailure;
								}
								else {
									if ([weak.delegate respondsToSelector:@selector(recKit:didFinishREC:)]) {
										[weak.delegate recKit:weak didFinishREC:url];
									}
									weak.internalState = BLRECStateFinished;
									NSData *beforeVideoData = [NSData dataWithContentsOfFile:kVideoOutPath];//未压缩的视频流
									NSLog(@"未压缩的视频大小： %.02fM", beforeVideoData.length/1024.0/1024);
								}
							}];
							/*
							AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];
                            [weak exportAVAsset:avAsset complete:^(NSError *error) {
                                if (error) {
                                    if ([weak.delegate respondsToSelector:@selector(recKit:didFailure:)]) {
                                        [weak.delegate recKit:weak didFailure:error];
                                    }
                                    weak.internalState = BLRECStateFailure;
                                }
                                else {
                                    if ([weak.delegate respondsToSelector:@selector(recKit:didFinishREC:)]) {
                                        [weak.delegate recKit:weak didFinishREC:[NSURL fileURLWithPath:kVideoOutPath]];
                                    }
                                    weak.internalState = BLRECStateFinished;
                                    NSData *beforeVideoData = [NSData dataWithContentsOfFile:kVideoOutPath];//未压缩的视频流
                                    NSLog(@"未压缩的视频大小： %.02fM", beforeVideoData.length/1024.0/1024);
                                }
                            }];
							 */
                        }
                        else {
                            excute_block_in_main_queue_safely(^{
								weak.internalState = BLRECStateFailure;
                                if ([weak.delegate respondsToSelector:@selector(recKit:didFailure:)]) {
                                    [weak.delegate recKit:weak didFailure:error];
                                }
                            });
                        }
                    }];
                }
            }];
        }
    }
}

- (void)captureSampleBuffer:(CMSampleBufferRef)sampleBuffer withBufferType:(RPSampleBufferType)bufferType error:(NSError *)error {
    NSLog(@"………………………………%@ %@", @(self.assetWriter.status), error);
    if (CMSampleBufferDataIsReady(sampleBuffer)) {
        if (self.assetWriter.status == AVAssetWriterStatusUnknown && bufferType == RPSampleBufferTypeVideo) {
            if ([self.assetWriter startWriting]) {
                [self.assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    // 偶然间appendSampleBuffer会crash，说会先调startSessionAtSourceTime，可是已经调了
                    self.sessionStarted = YES;
                });
            }
        }
        else if (self.assetWriter.status == AVAssetWriterStatusFailed) {
            [self stopScreenRecording];
            return;
        }
        else if (self.sessionStarted && self.assetWriter.status==AVAssetWriterStatusWriting) {
            
            switch (bufferType) {
                case RPSampleBufferTypeVideo:
                {
                    if (self.videoInput.isReadyForMoreMediaData) {
                        [self.videoInput appendSampleBuffer:sampleBuffer];
                    }
                }
                    break;
                case RPSampleBufferTypeAudioApp:
                {
                    if (self.audioInput.isReadyForMoreMediaData) {
                        [self.audioInput appendSampleBuffer:sampleBuffer];
                    }
                }
                    break;
                case RPSampleBufferTypeAudioMic:
                {
                    if (self.micInput.isReadyForMoreMediaData) {
                        [self.micInput appendSampleBuffer:sampleBuffer];
                    }
                }
                    break;
                default:
                    break;
            }
        }
    }
}

- (void)saveVideoToAlbum {
    if (@available(iOS 9.0, *)) {
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges: ^{
            [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:[NSURL URLWithString:kVideoOutPath]];
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            
        }];
    }
}

- (void)resetWriter {
    _assetWriter = nil;
    _audioInput = nil;
    _videoInput = nil;
    _micInput = nil;
}

- (AVAssetWriter *)assetWriter {
    if (!_assetWriter) {
        NSError *error;
        self.assetWriter = [AVAssetWriter assetWriterWithURL:[NSURL fileURLWithPath:kVideoOutPath] fileType:AVFileTypeMPEG4 error:&error];
    }
    return _assetWriter;
}

- (AVAssetWriterInput *)videoInput {
    if (!_videoInput) {
        CGSize videoSize = [UIScreen mainScreen].bounds.size;
        if (/*@available(iOS 11.0, *)*/0) {
            NSDictionary *videoCleanApertureSettings = @{
                                                         AVVideoCleanApertureWidthKey: [NSNumber numberWithFloat:videoSize.width],
                                                         AVVideoCleanApertureHeightKey: [NSNumber numberWithFloat:videoSize.height],
                                                         AVVideoCleanApertureHorizontalOffsetKey: [NSNumber numberWithInt:10],
                                                         AVVideoCleanApertureVerticalOffsetKey: [NSNumber numberWithInt:10],
                                                         };
            
            NSDictionary *compressionProperties = @{AVVideoProfileLevelKey         : AVVideoProfileLevelH264HighAutoLevel,
                                                    AVVideoH264EntropyModeKey      : AVVideoH264EntropyModeCABAC,
                                                    AVVideoAverageBitRateKey       : @(1920 * 1080 * 11.4),
                                                    AVVideoMaxKeyFrameIntervalKey  : @60,
                                                    AVVideoAllowFrameReorderingKey : @NO,
                                                    AVVideoCleanApertureKey        : videoCleanApertureSettings};
            NSNumber* width= [NSNumber numberWithFloat:videoSize.width];
            NSNumber* height = [NSNumber numberWithFloat:videoSize.height];
            
            NSDictionary *videoSettings = @{AVVideoCompressionPropertiesKey : compressionProperties,
                                            AVVideoCodecKey                 : AVVideoCodecH264,
                                            AVVideoWidthKey                 : width,
                                            AVVideoHeightKey                : height};
            
            self.videoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
        } else {
            // Fallback on earlier versions
            //写入视频大小
            NSInteger numPixels = videoSize.width * videoSize.height;
            //每像素比特
            CGFloat bitsPerPixel = 6.0;
            NSInteger bitsPerSecond = numPixels * bitsPerPixel;
            // 码率和帧率设置
            NSDictionary *compressionProperties = @{ AVVideoAverageBitRateKey : @(bitsPerSecond),
                                                     AVVideoExpectedSourceFrameRateKey : @(15),
                                                     AVVideoMaxKeyFrameIntervalKey : @(15),
                                                     AVVideoProfileLevelKey : AVVideoProfileLevelH264BaselineAutoLevel };
            NSDictionary *videoCompressionSettings = @{ AVVideoCodecKey : AVVideoCodecH264,
               AVVideoScalingModeKey : AVVideoScalingModeResizeAspectFill,
               AVVideoWidthKey : @(videoSize.width * 2),
               AVVideoHeightKey : @(videoSize.height * 2),
               AVVideoCompressionPropertiesKey : compressionProperties };
            self.videoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoCompressionSettings];
        }
    }
    return _videoInput;
}

- (AVAssetWriterInput *)audioInput {
    if (!_audioInput) {
        AudioChannelLayout acl;
        bzero( &acl, sizeof(acl));
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
        NSDictionary *audioOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                             [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                             [ NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
                                             [ NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
                                             [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey,
                                             [ NSData dataWithBytes: &acl length: sizeof( acl ) ], AVChannelLayoutKey,
                                             nil ];
        self.audioInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings];
    }
    return _audioInput;
}
- (AVAssetWriterInput *)micInput {
    if (!_micInput) {
        AudioChannelLayout acl;
        bzero( &acl, sizeof(acl));
        acl.mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
        NSDictionary *audioOutputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                             [ NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                             [ NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
                                             [ NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
                                             [ NSNumber numberWithInt: 64000 ], AVEncoderBitRateKey,
                                             [ NSData dataWithBytes: &acl length: sizeof( acl ) ], AVChannelLayoutKey,
                                             nil ];
//        if ([_assetWriter canApplyOutputSettings:audioOutputSettings forMediaType:AVMediaTypeAudio]) {
        self.micInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:audioOutputSettings];
//        }
    }
    return _micInput;
}

- (void)setInternalState:(RECState)internalState {
    _internalState = internalState;
    if ([self.delegate respondsToSelector:@selector(recKit:recStateChanged:)]) {
        [self.delegate recKit:self recStateChanged:internalState];
    }
}

- (void)exportAsset:(PHAsset *)videoAsset complete:(void(^)(NSError *error, NSURL *url))complete {
	PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
	options.version = PHImageRequestOptionsVersionCurrent;
	options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
	PHImageManager *manager = [PHImageManager defaultManager];
	[manager requestExportSessionForVideo:videoAsset options:options exportPreset:AVAssetExportPresetMediumQuality resultHandler:^(AVAssetExportSession * _Nullable exportSession, NSDictionary * _Nullable info) {
		exportSession.outputURL = [NSURL fileURLWithPath:kVideoOutPath];
		exportSession.shouldOptimizeForNetworkUse = NO;
		exportSession.outputFileType = AVFileTypeMPEG4;
		[exportSession exportAsynchronouslyWithCompletionHandler:^{
			excute_block_in_main_queue_safely(^{
				switch (exportSession.status) {
					case AVAssetExportSessionStatusCompleted:
						if (complete) {
							complete(exportSession.error, exportSession.outputURL);
						}
						break;
					default:
						if (complete) {
							complete(exportSession.error, exportSession.outputURL);
						}
						break;
				}
			});
		}];
	}];
}

- (void)exportAVAsset:(AVAsset *)avAsset complete:(void(^)(NSError *error))complete {
    // 导出视频到指定文件，MPEG4
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
    if ([compatiblePresets containsObject:AVAssetExportPresetHighestQuality]) {
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality];
        exportSession.outputURL = [NSURL fileURLWithPath:kVideoOutPath];
        exportSession.outputFileType = AVFileTypeMPEG4;
        exportSession.shouldOptimizeForNetworkUse= YES;
        [exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
            excute_block_in_main_queue_safely(^{
                if (complete) {
                    complete(exportSession.error);
                }
            });
        }];
    }
}

// 拿到《视频》相册的最后一个文件
- (void)loadLastestRecordVideo:(void(^)(NSError *error, NSData *data))callback {
    WEAKREF(self)
    PHFetchOptions *options = [[PHFetchOptions alloc] init];
    PHFetchOptions *fetchResoultOption = [[PHFetchOptions alloc] init];
    fetchResoultOption.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:false]];
    fetchResoultOption.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d",PHAssetMediaTypeVideo];
    PHFetchResult<PHAssetCollection *> *results = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumVideos options:options];
    for (PHAssetCollection *assetCollection in results) {
        if (assetCollection.assetCollectionType==PHAssetCollectionTypeSmartAlbum && assetCollection.assetCollectionSubtype==PHAssetCollectionSubtypeSmartAlbumVideos) {
//            PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
//            options.synchronous = YES;
            // 获得某个相簿中的所有PHAsset对象
            PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:options];
            PHAsset *asset = assets.firstObject;
            if (asset.mediaType == PHAssetMediaTypeVideo) {
                PHVideoRequestOptions *vidoeOptions = [[PHVideoRequestOptions alloc] init];
                [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:vidoeOptions resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
                    [weak exportAVAsset:asset complete:^(NSError *error) {
                        
                    }];
                    /*
                    NSURL *fileRUL = [asset valueForKey:@"URL"];
                    @autoreleasepool {
                        NSData *beforeVideoData = [NSData dataWithContentsOfURL:fileRUL];//未压缩的视频流
                        NSLog(@"未压缩的视频(%@)大小： %.02fM", fileRUL, beforeVideoData.length/1024.0/1024);
                        [JYPhotoVideoKit compressVideo:(PHAsset *)asset complete:^(NSError *error, NSData *data) {
                            NSLog(@"压缩后的视频大小： %.02fM", data.length/1024.0/1024);
                            if (callback) {
                                callback(error, data);
                            }
                        }];
                    }*/
                }];
            }
            else {
                if (callback) {
                    callback([NSError errorWithDomain:AVFoundationErrorDomain code:AVErrorUnknown userInfo:nil], nil);
                }
            }
            break;
        }
    }
}

@end

#import <CoreMedia/CoreMedia.h>
#import <AVFoundation/AVFoundation.h>

@implementation BLRECKit (Frame)

+ (UIImage *)frameFromVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time {
	AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
	NSParameterAssert(asset);
	AVAssetImageGenerator *assetImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
	assetImageGenerator.appliesPreferredTrackTransform = YES;
	assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
	
	UIImage *image = nil;
	NSTimeInterval dur = [self videoDuration:videoURL];
	NSTimeInterval st = time;
	do {
		NSError *error = nil;
		CGImageRef imageRef	= [assetImageGenerator copyCGImageAtTime:CMTimeMake(time, 60) actualTime:NULL error:&error];
		if (!error) {
			image = [[UIImage alloc] initWithCGImage:imageRef];
			CFRelease(imageRef);
			break;
		}
		else {
			st++;
		}
	} while (st<=dur);
	
	return image;
}

+ (NSTimeInterval)videoDuration:(NSURL *)videoURL {
	NSDictionary *opts = @{AVURLAssetPreferPreciseDurationAndTimingKey:@(NO)};
	AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:videoURL options:opts];  // 初始化视频媒体文件
	return urlAsset.duration.value / urlAsset.duration.timescale;
}
@end

@implementation JYPhotoVideoKit

+ (void)compressVideo:(PHAsset *)video complete:(void (^)(NSError *error, NSData *data))complete {
	NSURL *path = [video valueForKey:@"URL"];
	AVURLAsset *avAsset = [[AVURLAsset alloc] initWithURL:path options:nil];
	NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
	if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) {
		[[NSFileManager defaultManager] removeItemAtURL:self.tempURL error:nil];
		AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:AVAssetExportPreset640x480];
		exportSession.outputURL = [self tempURL];//设置压缩后视频流导出的路径
		exportSession.shouldOptimizeForNetworkUse = true;
		exportSession.outputFileType = AVFileTypeMPEG4;
		//异步导出
		[exportSession exportAsynchronouslyWithCompletionHandler:^{
			if (exportSession.status == AVAssetExportSessionStatusCompleted) {
				NSData *compressData = [NSData dataWithContentsOfURL:exportSession.outputURL];
				complete(nil, compressData.length?compressData:nil);
				NSError *error;
				[[NSFileManager defaultManager] removeItemAtURL:self.tempURL error:&error];
				NSLog(@"%@", error);
			}
			else{
				complete(exportSession.error, nil);
			}
		}];
	}
}

+ (NSURL *)tempURL {
	NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
	return [NSURL fileURLWithPath:[docPath.firstObject stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4",@"tempVideo"]]];
}

@end


